<!DOCTYPE html>

<html>
<head>
  <title>node.js</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="../../../docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
    <ul class="sections">
        
          <li id="title">
              <div class="annotation">
                  <h1>node.js</h1>
              </div>
          </li>
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-1">&#182;</a>
              </div>
              <p>Base class for all nodes in the parse tree. An instance of this class is
created for each parsed node, and then extended with one of the node-type
modules.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-keyword">import</span> util <span class="hljs-keyword">from</span> <span class="hljs-string">'../../util.js'</span>;
<span class="hljs-keyword">import</span> _ <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span> </span>{</pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-2">&#182;</a>
              </div>
              <p>Arguments passed in are defined by the canopy tool.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-keyword">constructor</span>(textValue, offset, elements, properties) {
    <span class="hljs-keyword">this</span>.textValue = textValue;
    <span class="hljs-keyword">this</span>.offset = offset;
    <span class="hljs-keyword">this</span>.elements = elements || [];

    <span class="hljs-keyword">this</span>.properties = properties;</pre></div></div>
            
        </li>
        
        
        <li id="section-3">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-3">&#182;</a>
              </div>
              <p>This is the current parser state (an instance
<a href="./parser_state.html">ParserState</a>.)</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">this</span>.state = Node.state;
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-4">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-4">&#182;</a>
              </div>
              <p>Node-type module to extend the Node instance with. Setting of this is
done by canopy during parsing and is setup in <a href="./parser.html">parser.js</a>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  set <span class="hljs-built_in">module</span>(mod) {
    _.extend(<span class="hljs-keyword">this</span>, mod);

    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.setup) {
      <span class="hljs-keyword">this</span>.setup();
    }

    _.forOwn(<span class="hljs-keyword">this</span>.definedProperties || {}, (methods, name) =&gt; {
      <span class="hljs-built_in">Object</span>.defineProperty(<span class="hljs-keyword">this</span>, name, methods);
    });

    <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.definedProperties;
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-5">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-5">&#182;</a>
              </div>
              <p>The SVG element to render this node into. A node-type class is
automatically added to the container. The class to set is defined on the
module set during parsing.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  set container(container) {
    <span class="hljs-keyword">this</span>._container = container;
    <span class="hljs-keyword">this</span>._container.addClass(<span class="hljs-keyword">this</span>.type);
  }

  get container() {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>._container;
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-6">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-6">&#182;</a>
              </div>
              <p>The anchor defined the points on the left and right of the rendered node
that the centerline of the rendered expression connects to. For most
nodes, this element will be defined by the normalizeBBox method in
<a href="../../util.html">Util</a>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  get anchor() {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.proxy) {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.proxy.anchor;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>._anchor || {};
    }
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-7">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-7">&#182;</a>
              </div>
              <p>Returns the bounding box of the container with the anchor included.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  getBBox() {
    <span class="hljs-keyword">return</span> _.extend(util.normalizeBBox(<span class="hljs-keyword">this</span>.container.getBBox()), <span class="hljs-keyword">this</span>.anchor);
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-8">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-8">&#182;</a>
              </div>
              <p>Transforms the container.</p>
<ul>
<li><strong>matrix</strong> - A matrix transform to be applied. Created using Snap.svg.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  transform(matrix) {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.container.transform(matrix);
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-9">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-9">&#182;</a>
              </div>
              <p>Returns a Promise that will be resolved with the provided value. If the
render is cancelled before the Promise is resolved, then an exception will
be thrown to halt any rendering.</p>
<ul>
<li><strong>value</strong> - Value to resolve the returned promise with.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  deferredStep(value) {
    <span class="hljs-keyword">return</span> util.tick().then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
      <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.cancelRender) {
        <span class="hljs-keyword">throw</span> <span class="hljs-string">'Render cancelled'</span>;
      }

      <span class="hljs-keyword">return</span> value;
    });
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-10">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-10">&#182;</a>
              </div>
              <p>Render this node.</p>
<ul>
<li><strong>container</strong> - Optional element to render this node into. A container
 must be specified, but if it has already been set, then it does not
 need to be provided to render.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  render(container) {
    <span class="hljs-keyword">if</span> (container) {
      <span class="hljs-keyword">this</span>.container = container;
    }

    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.proxy) {</pre></div></div>
            
        </li>
        
        
        <li id="section-11">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-11">&#182;</a>
              </div>
              <p>For nodes that proxy to a child node, just render the child.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.proxy.render(<span class="hljs-keyword">this</span>.container);
    } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-12">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-12">&#182;</a>
              </div>
              <p>Non-proxied nodes call their _render method (defined by the node-type
module).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">this</span>.state.renderCounter++;
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>._render()
        .then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
          <span class="hljs-keyword">this</span>.state.renderCounter--;
          <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
        });
    }
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-13">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-13">&#182;</a>
              </div>
              <p>Renders a label centered within a rectangle which can be styled. Returns
a Promise which will be resolved with the SVG group the rect and text are
rendered in.</p>
<ul>
<li><strong>text</strong> - String or array of strings to render as a label.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  renderLabel(text) {
    <span class="hljs-keyword">let</span> group = <span class="hljs-keyword">this</span>.container.group()
          .addClass(<span class="hljs-string">'label'</span>),
        rect = group.rect(),
        label = group.text(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, _.flatten([text]));

    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.deferredStep()
      .then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">let</span> box = label.getBBox(),
            margin = <span class="hljs-number">5</span>;

        label.transform(Snap.matrix()
          .translate(margin, box.height / <span class="hljs-number">2</span> + <span class="hljs-number">2</span> * margin));

        rect.attr({
          <span class="hljs-attr">width</span>: box.width + <span class="hljs-number">2</span> * margin,
          <span class="hljs-attr">height</span>: box.height + <span class="hljs-number">2</span> * margin
        });

        <span class="hljs-keyword">return</span> group;
      });
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-14">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-14">&#182;</a>
              </div>
              <p>Renders a labeled box around another SVG element. Returns a Promise.</p>
<ul>
<li><strong>text</strong> - String or array of strings to label the box with.</li>
<li><strong>content</strong> - SVG element to wrap in the box.</li>
<li><strong>options.padding</strong> - Pixels of padding to place between the content and
 the box.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  renderLabeledBox(text, content, options) {
    <span class="hljs-keyword">let</span> label = <span class="hljs-keyword">this</span>.container.text(<span class="hljs-number">3</span>, <span class="hljs-number">-3</span>, _.flatten([text])).addClass(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-keyword">this</span>.type}</span>-label`</span>);

    options = _.defaults(options || {}, {
      <span class="hljs-attr">padding</span>: <span class="hljs-number">0</span>
    });

    <span class="hljs-keyword">let</span> box = <span class="hljs-keyword">this</span>.container.rect()
          .addClass(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-keyword">this</span>.type}</span>-box`</span>)
          .attr({
            <span class="hljs-attr">rx</span>: <span class="hljs-number">3</span>,
            <span class="hljs-attr">ry</span>: <span class="hljs-number">3</span>
          });
    <span class="hljs-keyword">if</span>(options.type){
      box = <span class="hljs-keyword">this</span>.container.rect()
          .addClass(<span class="hljs-string">`<span class="hljs-subst">${options.type}</span>-box`</span>)
          .attr({
            <span class="hljs-attr">rx</span>: <span class="hljs-number">3</span>,
            <span class="hljs-attr">ry</span>: <span class="hljs-number">3</span>
          });
    }

    <span class="hljs-keyword">this</span>.container.prepend(label);
    <span class="hljs-keyword">this</span>.container.prepend(box);

    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.deferredStep()
      .then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">let</span> labelBox = label.getBBox(),
            contentBox = content.getBBox(),
            boxWidth = <span class="hljs-built_in">Math</span>.max(contentBox.width + options.padding * <span class="hljs-number">2</span>, labelBox.width),
            boxHeight = contentBox.height + options.padding * <span class="hljs-number">2</span>;</pre></div></div>
            
        </li>
        
        
        <li id="section-15">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-15">&#182;</a>
              </div>
              <p>//matrix(1,0,0,1,-6,75)
matrix = matrix.add(1,0,0,1,0,10);</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
        label.transform(Snap.matrix()
          .translate(<span class="hljs-number">0</span>, labelBox.height));

        box.transform(Snap.matrix()
          .translate(<span class="hljs-number">0</span>, labelBox.height))
          .attr({
            <span class="hljs-attr">width</span>: boxWidth,
            <span class="hljs-attr">height</span>: boxHeight
          });

        content.transform(Snap.matrix()
          .translate(boxWidth / <span class="hljs-number">2</span> - contentBox.cx, labelBox.height + options.padding));
      });
  }
};</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>
